package com.xiaoxie.quartz.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xiaoxie.common.constant.Constants;
import com.xiaoxie.common.enums.ReturnCode;
import com.xiaoxie.common.exception.BizException;
import com.xiaoxie.quartz.domain.JobEntity;
import com.xiaoxie.quartz.domain.dto.GroupDto;
import com.xiaoxie.quartz.domain.dto.JobDto;
import com.xiaoxie.quartz.domain.dto.QueryJobDto;
import com.xiaoxie.quartz.mapper.JobMapper;
import com.xiaoxie.quartz.service.QuartzService;
import com.xiaoxie.quartz.util.CronUtils;
import com.xiaoxie.quartz.util.JobClassCheck;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.ClassUtils;
import org.quartz.*;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

@Service
public class QuartzServiceImpl implements QuartzService {

    @Resource
    private JobMapper jobMapper;

    private final SchedulerFactoryBean schedulerFactoryBean;

    public QuartzServiceImpl(SchedulerFactoryBean schedulerFactoryBean) {
        this.schedulerFactoryBean = schedulerFactoryBean;
    }

    @Transactional
    @Override
    public void addJob(String jobClassName, String jobName, String jobGroup, String cronExpression,String description,int InitStatus) throws SchedulerException, ClassNotFoundException {

        if(!JobClassCheck.isJobClass(jobClassName)) {
            throw new BizException(ReturnCode.JOB_CLASS_NOT_EXIST);
        }
        boolean valid = CronUtils.isValid(cronExpression);
        if (!valid) {
            // cron表达式无效
            throw new BizException(ReturnCode.CRON_EXPRESSION_ERROR);
        }
        if (jobName.isEmpty() || jobGroup.isEmpty()) {
            throw new BizException(ReturnCode.JOB_NAME_OR_JOB_GROUP_EMPTY);
        }

        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        if (scheduler.checkExists(jobKey)) {
            // 任务已存在
            throw new BizException(ReturnCode.JOB_EXISTS);
        }

        Class<?> aClass = ClassUtils.getClass(jobClassName);
        JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) aClass)
                .withIdentity(jobName, jobGroup)
                .withDescription(description)
                .build();
        CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                .withIdentity(jobName, jobGroup)
                .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
                .build();
        scheduler.scheduleJob(jobDetail, cronTrigger);

        // 保持暂停状态
        if (InitStatus == 0) {
            pauseJob(jobName, jobGroup);
        }
    }

    @Override
    public void pauseJob(String jobName, String jobGroup) throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        scheduler.pauseJob(jobKey);
    }

    @Transactional
    @Override
    public void resumeJob(String jobName, String jobGroup) throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobKey jobkey = JobKey.jobKey(jobName, jobGroup);
        scheduler.resumeJob(jobkey);
    }

    @Transactional
    @Override
    public void deleteJob(String jobName, String jobGroup) throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        scheduler.deleteJob(jobKey);
    }

    @Transactional
    @Override
    public void triggerJob(String jobName, String jobGroup) throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        scheduler.triggerJob(jobKey);
    }

    @Transactional
    @Override
    public void updateJob(String jobClass, String jobName, String jobGroup, String cronExpression, String description,Integer initStatus) throws SchedulerException, ClassNotFoundException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        // 检查任务是否存在
        if (scheduler.checkExists(jobKey)) {
            // 删除现有任务
            deleteJob(jobName, jobGroup);
        }
        // 添加新的任务
        addJob(jobClass, jobName, jobGroup, cronExpression,description,initStatus);
    }

    @Override
    public List<GroupDto> getAllGroups() {
        return jobMapper.getAllGroups();
    }

    @Override
    public List<JobDto> getJobsByGroup(String jobGroup) {
        return jobMapper.getJobsByGroup(jobGroup);
    }

    @Override
    public PageInfo<JobEntity> getJobList(Integer pageNum, QueryJobDto queryJobDto) {
        JobEntity jobEntity = new JobEntity();
        BeanUtils.copyProperties(queryJobDto, jobEntity);
        PageHelper.startPage(pageNum, Constants.PAGE_SIZE);
        List<JobEntity> data = jobMapper.getJobList(jobEntity, queryJobDto.getTriggerStatusList());
        PageInfo<JobEntity> info = new PageInfo<>(data);
        return info;
    }

    @Override
    public boolean checkJobGroupAndJobName(String jobGroup, String jobName) {
        int count = jobMapper.countByJobGroupAndJobName(jobGroup,jobName);
        return count > 0;
    }

    @Override
    public boolean checkJobClassName(String jobClassName) {
        // 判断jobClassName是否为实现Job接口
        return JobClassCheck.isJobClass(jobClassName);
    }

    @Override
    public boolean checkCronExpression(String cronExpression) {
        return CronUtils.isValid(cronExpression);
    }

    @Override
    public JobEntity getByGroupNameAndJobName(String jobGroup, String jobName) {
        return jobMapper.getJobByGroupNameAndJobName(jobGroup,jobName);
    }
}
